'use strict';
var crypto = require('crypto');
var fs = require('fs'); 
var city=require('./city');
var ipip=require('./IpIp')();
var http = require("http");
var utils = exports = module.exports = {};

var iosIgnore='androidimei,androidid';
var androidIgnore='cid';

utils.requestValid = function(req,keys){

	var version = req.query.version;
	var t = req.query.t;
	var headers = req.headers;
	var token =  headers['accept-protocol'];

	if(!version || !t || !token ) return false;
	
	var ct = new Date().getTime();
	if(ct - t > 60000) return false;
	version = version.substring(0,version.indexOf('.'))

	if(!version || !keys[version+'']) return false;
	
	
	var key = keys[version+''].hardKey
	if (md5Digest(key+t) != token) return false;
	
	return true;
	
}

utils.getAppKey = function(req,keys){
	var version = req.query.version;
	version = version.substring(0,version.indexOf('.'))
	return keys[version+'']
}

utils.getClientIP = function(req){ 
	var ipAddress; 
	var headers = req.headers; 
	var forwardedIpsStr = headers['x-real-ip'] || headers['x-forwarded-for']; 
	forwardedIpsStr ? ipAddress = forwardedIpsStr : ipAddress = null; 
	if (!ipAddress) { 
		ipAddress = req.connection.remoteAddress; 
		} 
	if(ipAddress && ipAddress.length > 15){
		var ips = ipAddress.split(",");
		if(ips.length > 1 && ips[1].length > 6) ipAddress=ips[1].trim();
	}
	return ipAddress; 
}
 
utils.getAreaByIp  = function(ip){

	if(!ip || ip.length < 7)return null;
	
	return ipip(ip,'array').join(",");
}


function md5Digest(param){
	var md5 = crypto.createHash('md5'); 
	md5.update(param);
	return md5.digest('hex');
}
utils.sha1Digest=function(param){
	var md5 = crypto.createHash('sha1'); 
	md5.update(param);
	return md5.digest('hex');
}

utils.digest  = function(param){
	return md5Digest(param);
}

function cipheriv(en, code, data) {
      var buf1 = en.update(data, code), buf2 = en.final();
      var r = new Buffer(buf1.length + buf2.length);
      buf1.copy(r); buf2.copy(r, buf1.length);
      return r;
};

utils.desEncrypt   = function(param,key,iv){
	
	if(key.length <8){
		key += '00000000'.substring(0,8-key.length)
	}else if(key.length >8){
		key = key.substring(0,8)
	}
	key = new Buffer(key);
  iv = new Buffer(iv ? iv : 0)
	return  cipheriv(crypto.createCipheriv('des-ecb', key, iv), 'utf8', param).toString('hex');
 
}

utils.desDecrypt  = function(param,key,iv){
	if(key.length <8){
		key += '00000000'.substring(0,8-key.length)
	}else if(key.length >8){
		key = key.substring(0,8)
	}
	key = new Buffer(key);
  iv = new Buffer(iv ? iv : 0)
	return cipheriv(crypto.createDecipheriv('des-ecb', key, iv), 'hex', param) .toString('utf8');
	
}


utils.deepCopy = function deepCopy(source) { 
		var result=null;
		if(source instanceof Array) result=[];
		else result={};
		
    

    for (var key in source) {

      result[key] = (typeof source[key]==='object' && source[key] != null)? deepCopy(source[key]): source[key];

   } 
   return result; 
}

utils.areaCheck = function areaCheck(source,directArea) {

	var areas = directArea.split(',');
	for(var i =0;i< areas.length;i++){
		if(areas[i] !='' && source.indexOf(areas[i]) >= 0) return true;
	}

	var provin=''
	for(var province in city){
		for(var i =0;i< city[province].length;i++){
			if(source.indexOf(city[province][i]) >= 0){
				provin = province;
				break;
			}
		}
		if(provin !='') break;
	}

	if(provin !='' && directArea.indexOf(provin) >= 0) return true;
	return false;

}


utils.arrayConcat = function(q,b){
	for (var i=0; i < b.length; i++) {
    q.push( b[i] );
	}
}

utils.versionCompare = function(v1,v2){
	if(v1 == v2) return 0;
	var version1 = v1.split(".");
	var version2 = v2.split(".");
	var length = Math.min(version1.length,version2.length);
	for(var i=0;i<length;i++){
		var num = Number(version1[i]);
		if( num < Number(version2[i])) return -1;	
		if( num > Number(version2[i])) return 1;		
	}
	if(version1.length < version2.length) return -1;
	if(version1.length > version2.length) return 1;
	return 0;
}


utils.isValidIP = function(ip)     
{     
    var reg =  /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/     
    return reg.test(ip);     
}

utils.getOsv = function(req){
	if(req.query.w && req.query.h){
		if(req.query.w=='1080' && req.query.h=='1622') return '6P';
		if(req.query.w=='750' && req.query.h=='1126') return '6S';
		if(req.query.w=='640' && req.query.h=='960') return '5S';
		if(req.query.w=='640' && req.query.h=='784') return '4S';
	}
	if(req.query.width && req.query.height){
		if(req.query.width=='414' && req.query.height=='736') return '6P';
		if(req.query.width=='375' && req.query.height=='667') return '6S';
		if(req.query.width=='320' && req.query.height=='568') return '5S';
		if(req.query.width=='320' && req.query.height=='480') return '4S';
	}
	
}

utils.formateDate = function(da){
	if(!da) return null;
	return da.getTime();
}

utils.paramFormate = function(params){
	var param='';
	for(var key in params){
		param += key+'='+params[key]+'&';
	}
	return param;
}



utils.arrayPage = function(list,start,count,properties){
	var length = list.length;
	var end = start+count;
	var result=[];
	
	if(start > length) return result;
	
	if(end > length) end = length;
	
	for(var i= start;i<end;i++){
		result.push(getObjOrByProperties(list[i],properties));
	}
	return result;
}

function getObjOrByProperties(src,properties){
	if(properties){
			var obj={};
			for(var j=0;j<properties.length;j++){
				obj[properties[j]] = src[properties[j]];
			}
			return obj;
		}
		return src;
}

utils.findByPorperty =function(list,val,key){
	if(!list) return null;
	for(var i=0;i<list.length;i++){
		if(list[i][key] == val) return list[i];
	}
	
	return null;
}

utils.searchByKey =function(list,val,key,total,need,properties,start){
	if(!list) return null;
	var founds=[];
	var vals = val.split(',');
	for(var i=0;i<list.length;i++){
		var keyVal = list[i][key] ;
		if(!keyVal) continue;
		var unfit = false;
		for(var j=0;j<vals.length;j++){
			if(keyVal.indexOf(vals[j]) <0){
				unfit = true;
				break;
			}
		}
		
		if(!unfit){
				founds.push(getObjOrByProperties(list[i],properties));
			}
		
		if(founds.length > total) break;
	}

	if(start+1 > founds.length) return [];
	var end = total;
	if(founds.length < total) end = founds.length
	
	return founds.slice(start,end);
}

utils.findLikePorpertys =function(list,val,key,total,need,properties){
	if(!list) return null;
	var counts={};
	var founds=[];
	for(var i=0;i<list.length;i++){
		var keyVal = list[i][key] ;
		if(!keyVal) continue;
		var keys =keyVal.split(',');
		for(var j=0;j<keys.length;j++){
			if(val.indexOf(keys[j]) >=0){
				if(!counts[keys[j]]) counts[keys[j]] = 1;
				if(counts[keys[j]] > 4) break;
				
				counts[keys[j]] = counts[keys[j]] +1;		
				founds.push(getObjOrByProperties(list[i],properties));
				break;
			}
		}
		
		if(founds.length > total) break;
	}

	if(founds.length <= need) return  founds;
	
	var needs=[]
	for(var i=0;i<need;i++){
		var ind = Math.floor(Math.random()*founds.length);
		needs.push(founds[ind]);
		founds.splice(ind, 1);
	}
	
	return needs;
}

utils.uuid =function () {
		var t = new Date().getTime();
    return 'xxxxxyxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
        return v.toString(16);
    }) + t;
}

utils.folderCheck = function(folder){
	fs.exists(folder,function(exists){
     if(!exists) fs.mkdir(folder)
  })
}

utils.getDateString = function(withHour){
	var myDate = new Date();
	var day = myDate.getFullYear()+'-'+ numFormate(myDate.getMonth()+1)+'-'+numFormate(myDate.getDate());
	if(withHour) day+= numFormate(myDate.getHours())
	return day;
}

function numFormate(num){
	return num >9?num:('0'+num);
}


utils.randomAry = function(total,max){

	var result=[]
	if(total ==0) return result;
	
	var num = total;	
	if(num >max) num =max;
	if(num <max && num>max/2) num=max/2;
	
	if( num > total) num=total;
	var ids=[];
	for(var i=0;i<total;i++){
		ids.push(i)
	}
	
	for(var i=0;i<num;i++){
		var len = ids.length;
		var ind = Math.floor(Math.random()*len);	
		result.push(ids[ind])
		ids.splice(ind,1);
		
	}
	return result;
}

utils.request = function(option,callBack){
	var req = requestWithTimeout(option,5000, callBack
	).on("error", function(e) {
	}).on('timeout',function(e){
		
    	callBack([]);
});
	 
	req.end();
	
}

function requestWithTimeout(options,timeout,callBack){
    var timeoutEventId,
        req=http.request(options,function(res){
        	
        	var chunks = [];
				    res.on("data", function(chunk) {
				        chunks.push(chunk);
				    });
            res.on('end',function(){
                clearTimeout(timeoutEventId);
                
                var buffer = Buffer.concat(chunks);
					      var encoding = res.headers['content-encoding'];
					      if (encoding == 'gzip') {
					        zlib.gunzip(buffer, function(err, decoded) {
					        	callBack(decoded && decoded.toString())
					        });
					      } else if (encoding == 'deflate') {
					        zlib.inflate(buffer, function(err, decoded) {
					          callBack(decoded && decoded.toString())
					        })
					      } else {
					        callBack(buffer.toString());
					      }
            });
            
            res.on('close',function(){
                clearTimeout(timeoutEventId);
                console.log('close...');
            });
            
            res.on('abort',function(){
                console.log('abort...');
               
            });
        });
        
    		req.on('timeout',function(e){		       
		        req.abort();
		    });
    
    
		    timeoutEventId=setTimeout(function(){
		        req.emit('timeout',{message:'have been timeout...'});
		    },timeout);
    
    return req;
}